package com.atguigu.tingshu.order.adapder;

import com.atguigu.tingshu.account.client.UserAccountFeignClient;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.model.order.LocalMsg;
import com.atguigu.tingshu.order.mapper.LocalMsgMapper;
import com.atguigu.tingshu.order.service.OrderInfoService;
import com.atguigu.tingshu.vo.account.AccountLockResultVo;
import com.atguigu.tingshu.vo.account.AccountLockVo;
import com.atguigu.tingshu.vo.order.OrderInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class RechargePayWayImpl implements PayWays {

    @Qualifier("com.atguigu.tingshu.account.client.UserAccountFeignClient")
    @Autowired
    private UserAccountFeignClient userAccountFeignClient;
    @Autowired
    private OrderInfoService orderInfoService;
    @Autowired
    private RabbitService rabbitService;
    @Autowired
    private LocalMsgMapper localMsgMapper;

    @Override
    public Boolean supportPayWay(String payWay) {
        return "1103".equals(payWay);
    }

    /**
     * 当解锁和扣减操作失败后
     * 本地定时任务进行重试
     * 扫描本地信息表
     */
    @Scheduled(fixedDelay = 1000 * 60 * 60)
    public void scanLocalMsg() {
        LambdaQueryWrapper<LocalMsg> queryWrapper = new LambdaQueryWrapper<LocalMsg>().eq(LocalMsg::getStatus, 0);
        List<LocalMsg> localMsgList = localMsgMapper.selectList(queryWrapper);
        for (LocalMsg localMsg : localMsgList) {
            String orderNo = localMsg.getMsgContent();
//            rabbitService.sendMessage(MqConst.EXCHANGE_ACCOUNT, MqConst.ROUTING_ACCOUNT_UNLOCK, orderNo);
            rabbitService.sendMessage(MqConst.EXCHANGE_ACCOUNT, MqConst.ROUTING_ACCOUNT_MINUS, orderNo);
        }

    }
    @Override
    public void payWay(OrderInfoVo orderInfoVo, String orderNo, Long userId) {
        //判断余额是否充足(rpc方式同步调用账户微服务获取账户余额锁定信息)
        AccountLockVo accountLockVo = prepareAccountData(orderInfoVo, orderNo, userId);
        Result<AccountLockResultVo> accountLockResultVoResult = userAccountFeignClient.checkAndLockAccount(accountLockVo);
        if (accountLockResultVoResult.getCode() != 200) {
            throw new GuiguException(ResultCodeEnum.ACCOUNT_LOCK_ERROR);
        }

        try {
            // 保存订单
            orderInfoService.saveOrderInfo(orderInfoVo,orderNo,userId);
            //扣减余额()
            rabbitService.sendMessage(MqConst.EXCHANGE_ACCOUNT,MqConst.ROUTING_ACCOUNT_MINUS,orderNo);
            //支付成功进行操作
            orderInfoService.paySuccess(orderNo);
        } catch (GuiguException e) {
            // 保存订单失败反向去修改账户微服务下的账户信息（user_account的锁定账户余额和可用账户余额）
            rabbitService.sendMessage(MqConst.EXCHANGE_ACCOUNT, MqConst.ROUTING_ACCOUNT_UNLOCK, orderNo);
        }catch (Exception e){
            //扣减失败重新发消息扣减
            rabbitService.sendMessage(MqConst.EXCHANGE_ACCOUNT, MqConst.ROUTING_ACCOUNT_MINUS, orderNo);
        }

    }

    /**
     * 封装账户锁定信息
     * @param orderInfoVo 订单信息
     * @param orderNo 订单号
     * @param userId 用户id
     * @return 账户锁定信息
     */
    private AccountLockVo prepareAccountData(OrderInfoVo orderInfoVo, String orderNo, Long userId) {
        AccountLockVo accountLockVo = new AccountLockVo();
        accountLockVo.setOrderNo(orderNo);
        accountLockVo.setUserId(userId);
        accountLockVo.setAmount(orderInfoVo.getOrderAmount());
        accountLockVo.setContent(orderInfoVo.getOrderDetailVoList().get(0).getItemName());
        return accountLockVo;
    }
}
